<?php
/**
 * 装饰器模式
 * 结构型设计模式
 * 向一个现有的对象添加新的功能，同时又不改变其结构
 */

spl_autoload_register('autoload');

function autoload($class) 
{
    require dirname($_SERVER['SCRIPT_FILENAME']) . '//..//' . str_replace('\\', '/', $class) . '.php';
}

/*============================= 测试 =============================*/
use decorator\Person;
use decorator\Sandals;
use decorator\Shorts;
use decorator\Tshirt;

$person = new Person("欧阳");
$tshirt = new Tshirt($person); //T恤
$shorts = new Shorts($tshirt); //短裤
$sandals = new Sandals($shorts); //拖鞋
$sandals->show();

/*
小结：
装饰器模式就是对现有的类进行加工包装，与传统的继承重写方法不同，是一种类的组合方式。
装饰器模式允许向一个现有的对象添加新的功能，同时又不改变其结构。
这种类型的设计模式属于结构型模式，它是作为现有的类的一个包装。

使用场景： 
1、扩展一个类的功能
2、动态增加功能，动态撤销
举个栗子：对文本进行大小、颜色进行加工，对前端的响应和请求进行加工

优点：
把类的装饰功能从类中搬移到其它类中，简化了原有的类
也就是说把核心功能和装饰功能区分开来，功能上解耦
装饰类和被装饰类可以独立发展，不会相互耦合，装饰器模式是继承的一个替代模式，装饰器模式可以动态扩展一个实现类的功能。

缺点：
多层装饰比较复杂
需要注意装饰的顺序，假如我们有一个功能需要先过滤非法字符再加密，两个装饰功能就不能搞反了
比如在laravel中，中间件就是一个装饰器，对客户端的请求(匿名类Closure)进行拦截，并且做一系列动作，
比如验证token、cookie加解密等
*/

